// **************************************************************
// COPYRIGHT(c)2010, xidian University
// All rights reserved.
//
// IP LIB INDEX  :  IP lib index just sa UTOPIA_B
// IP Name       :  FIFO
// File name     :  fifo.v
// Module name   :  FIFO
// Full name     :  
//
// Author        :  Pan Wei-tao
// Email         :  panweitao@163.com
// Date          :  2011-01-05
// Version       :  V 1.0
//
//Abstract       :
// Called by     :  
//
// Modification history
// ------------------------------------------------------------------------------------------------------
// //
// $Log$   64X32bits  ASY
//
// *********************************************************************

`define DLY 0  
// `include    "top_define.v"

module rx_data_fifo (
                //INPUT
//                 fifo_en                  ,
//                 fifo_clr                 ,
                 clock                     ,
                 rst_n                     ,
                ram_2p_cfg_register         ,
//                 rclk                     ,
//                 rrst_n                   ,
                 fifo_wen                 ,
                 fifo_wdata               ,
                 fifo_ren                 ,
                //OUTPUT
                 fifo_rdata               ,
                 fifo_full_wr             ,
                 fifo_empty_rd            ,           
//                 fifo_cnt_wr              
                 almost_full
                 );  

// define parameters
parameter     PTR      =  7              ;    // address width of FIFO (3 if 8,4 if 16,5 if 32)
parameter     WORDS    =  128             ;    // decimal depth of FIFO (8, 16, 32)
parameter     W_SIZE   =  256             ;    // size of FIFO word (8, 16, 24 or 32)
parameter     A_FULL   =  126             ;
//input from write interface
input                   clock              ;    // write clock signal
input                   rst_n            ;    // write reset signal
input       [9:0]       ram_2p_cfg_register;
//input                   fifo_en           ;    // fifo enable signal
//input                   fifo_clr          ;    // fifo clear signal,it can reset the write and read address

//input from read interface
//input                   rclk              ;    // read clock signal
//input                   rrst_n            ;    // read reset signal

//input from write fifo port
input                   fifo_wen          ;    // fifo write enable signal
input  [W_SIZE-1 : 0]   fifo_wdata        ;    // fifo write data

//input/output from read fifo port
input                   fifo_ren          ;    // fifo read enable signal
output [W_SIZE-1 : 0]   fifo_rdata        ;    // fifo read data

//clock domain
output                  fifo_full_wr      ;    // fifo write full flag signal
//output    [     (PTR):0]   fifo_cnt_wr          ;    // FIFO word counter in the write clock domain
//output                  fifo_empty_wr     ;    // the empty num of write fifo
//rclk domain
output                  fifo_empty_rd     ;    // fifo read empty flag signal
//output                  fifo_full_rd      ;    // the data num of read fifo
output                  almost_full       ;

//*************************************************

reg    [     (PTR):0]   wr_grad              ;    // FIFO write pointer of grad code
reg    [     (PTR):0]   wr_grad_next         ;    // next FIFO write pointer of grad code
reg    [     (PTR):0]   wr_bin               ;    // FIFO write pointer of binary code
reg    [     (PTR):0]   wr_bin_next          ;    // next FIFO write pointer of binary code
             
reg    [     (PTR):0]   wr_grad_ff1          ;    //resyn the wr_grad to the read clock domain
reg    [     (PTR):0]   wr_grad_ff2          ;
             
reg    [     (PTR):0]   rd_bin_wr            ;    //The binary read address in the write clock domain
             
reg    [     (PTR):0]   rd_grad              ;    // FIFO read pointer of grad code
reg    [     (PTR):0]   rd_grad_next         ;    // next FIFO read pointer of grad code
reg    [     (PTR):0]   rd_bin               ;    // FIFO read pointer of binary code
reg    [     (PTR):0]   rd_bin_next          ;    // next FIFO read pointer of binary code
             
reg    [     (PTR):0]   rd_grad_ff1          ;    // resyn the rd_grad to the write clock domain
reg    [     (PTR):0]   rd_grad_ff2          ;
             
reg    [     (PTR):0]   wr_bin_rd            ;    // The binary write address in the read clock domain
             
reg    [     (PTR):0]   wr_grad_addr         ;
reg    [     (PTR):0]   rd_grad_addr         ;
             
reg    [     (PTR):0]   fifo_cnt_wr          ;    // FIFO word counter in the write clock domain
//reg    [     (PTR):0]   fifo_cnt_rd          ;    // FIFO word counter in the read clock domain
       
       
reg                     fifo_full_wr         ;    // full flag in the write clock domain
       
reg                     fifo_empty_rd        ;    // empty flag in the read clock domain
       
reg                     wen                  ;    // write enable into dpram
       
reg    [W_SIZE-1 : 0]   dpram_wdata          ;
       
reg    [   (PTR-1):0]   waddr                ;    // write address bus into dpram
wire   [   (PTR-1):0]   raddr                ;    // read  address bus into dpram
// wire                    fifo_empty_wr        ;
// wire                    fifo_full_rd         ;       
wire   [W_SIZE-1 : 0]   dpram_rdata          ;

reg                     almost_full          ;


//---------------------------------------------------------------------------
// FIFO write address control
//
//---------------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////////
//assign the next binary address
///////////////////////////////////////////////////////////////////////////

//always @(wr_bin)
//begin
//    wr_bin_next = wr_bin + 7'b1;
//end

///////////////////////////////////////////////////////////////////////////
//assignment of  the binary address for the dpram
///////////////////////////////////////////////////////////////////////////
always @ (posedge clock or negedge rst_n)
begin
    if (rst_n==1'b0)
        begin
            wr_bin <= 'b0;
        end
//    else if(fifo_clr==1'b1)
//        begin
//            wr_bin <=  'b0;
//        end
    else if((fifo_wen==1'b1)&&(fifo_full_wr==1'b0)) //&&(fifo_en == 1'b1))
        begin
            wr_bin <=  wr_bin + 3'b1;
        end
    else
        wr_bin <=  wr_bin;
end


//-------------------------------------------------------------------------------------
//
//FIFO read address control
//
//-------------------------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////////
//generate the next binary address
///////////////////////////////////////////////////////////////////////////

//always @(rd_bin)
//begin
//    rd_bin_next = rd_bin + 7'b1;
//end

///////////////////////////////////////////////////////////////////////////
//generate the binary address for the dpram
///////////////////////////////////////////////////////////////////////////
always @ (posedge clock or negedge rst_n)
begin
    if (rst_n==1'b0)
        begin
            rd_bin <=  'b0;
        end
//    else if(fifo_clr==1'b1)
//        begin
//            rd_bin <=  'b0;
//        end
    else if((fifo_ren==1'b1)&&(fifo_empty_rd==1'b0)) //&&(fifo_en == 1'b1))
        begin
            rd_bin <=  rd_bin + 3'b1;
        end
    else
        rd_bin <=  rd_bin;
end

//---------------------------------------------------------------------------------
//
//assign the fifo_cnt_wr and fifo_cnt_rd
//
//---------------------------------------------------------------------------------
//always @ (wr_bin or rd_bin)
//begin
//    fifo_cnt_rd = (wr_bin - rd_bin) ;
//end

always @ (rd_bin or wr_bin)
begin
   fifo_cnt_wr = (wr_bin - rd_bin) ;
end

always @ (fifo_cnt_wr)
begin
    if(fifo_cnt_wr>=A_FULL)
        almost_full=1'b1;
    else
        almost_full=1'b0;
end

//---------------------------------------------------------------------------------
//
//assign the fifo full and empty flag
//
//---------------------------------------------------------------------------------
always @ (wr_bin or rd_bin)
begin
    if((wr_bin[PTR]!=rd_bin[PTR])&&
            (rd_bin[PTR-1:0]==wr_bin[PTR-1:0]))
        fifo_full_wr   = 1'b1;
    else
        fifo_full_wr   = 1'b0;
end



always @ (wr_bin or rd_bin)
begin
    if (wr_bin==rd_bin)
        fifo_empty_rd  = 1'b1;
    else
        fifo_empty_rd  = 1'b0;
end

// assign   fifo_empty_wr = fifo_empty_rd;
// assign   fifo_full_rd  = fifo_full_wr;
//------------------------------------------------------
//
//write enable signal for dpram, it will be delay a clock cycle
//
//--------------------------------------------------------

always @ (posedge clock or negedge rst_n)
begin
    if (rst_n==1'b0)
        wen <= 1'b0;
    else if ((fifo_wen==1'b1)&&(fifo_full_wr==1'b0))  //&&(fifo_en==1'b1))
        wen <=  1'b1;
    else
        wen <=  1'b0;
end



//--------------------------------------------------------
//
//write data bus of dpram
//
//--------------------------------------------------------
always @ (posedge clock or negedge rst_n)
begin
    if (rst_n==1'b0)
        dpram_wdata <= 'b0;
    else if(fifo_wen && (!fifo_full_wr)) // && fifo_en)
        dpram_wdata <=  fifo_wdata;
end


//--------------------------------------------------------
//
//read data bus of dpram
//
//--------------------------------------------------------

assign fifo_rdata =  dpram_rdata;

//-------------------------------------------------------
//
//write address assign for the dpram
//
//-------------------------------------------------------

always @ (posedge clock or negedge rst_n)
begin
    if (rst_n==1'b0)
        waddr <= 'b0;
    else
        waddr <=  wr_bin [(PTR-1):0];
end


//-------------------------------------------------------
//
//read address assign for the dpram
//
//-------------------------------------------------------

assign raddr = rd_bin [(PTR-1):0];


ram_2p_d128_w256_wrapper U_ram_2p_d128_w256_wrapper (
    .clk(clock),
    .ram_2p_cfg_register(ram_2p_cfg_register),
    // .wren(fifo_wen),
    .wren(wen),
    .waddr(waddr),
    .wdata(dpram_wdata),
    .rden(fifo_ren),
    .raddr(raddr),
    .rdata(dpram_rdata)
);

                             

endmodule

